#include "detachCommand.h"
#include "threadPool.h"
#include "proprocessReq.h"
#include "userOperator.h"
#include "database.h"
#include "func.h"

int getusername(const char* id,char* username){ //根据返回的id,获取username;
    memset(username,0,strlen(id)+1);
    memcpy(username,id+5,strlen(id)-5);
    return 0;
}

int business(task_t* ptask,MYSQL *mysql){    //线程池的业务
    //1.接受当前工作路径
    /* printf("netfd = %d,username = %s,command = %s\n",ptask->netfd,ptask->username,ptask->command); */
    train_t train;
    memset(&train,0,sizeof(train_t));
    recvn(ptask->netfd,&train.length,sizeof(train.length));
    recvn(ptask->netfd,train.data,train.length);
    char curWorkDir[1024] = {0};
    memcpy(curWorkDir,train.data,train.length);
    /* printf("curWorkDir = %s\n",curWorkDir); */
    //2.构建路径栈
    // 分割当前目录的路径
    char* arguments[1024];
    int arglen;
    arglen = 0;
    char* saveptr;
    arguments[0] = strtok_r(curWorkDir,"/",&saveptr);
    if(arguments[0]!=NULL){
        ++arglen;
    }
    for(int i=1;i<1024;++i){
        arguments[i] = strtok_r(NULL,"/",&saveptr);
        if(arguments[i]==NULL){
            break;
        }
        ++arglen;    
    }
    pathStack_t pathStack;
    //恢复栈的内容
    pathStackInit(&pathStack);
    for(int idx = 0;idx < arglen;++idx){
        pushPathStack(&pathStack,arguments[idx]);
    }
    //3.判断任务类型,并执行具体的任务
    cmdShare_t cmdShare;    
    cmdShare.netfd = ptask->netfd;
    memset(cmdShare.username,0,sizeof(cmdShare.username));
    memcpy(cmdShare.username,ptask->username,strlen(ptask->username)+1);
    cmdShare.mysql = mysql;
    cmdShare.pathStack = pathStack;
    int ret = handlePutsAndGets(&cmdShare,ptask->command);
    return ret;
}

int handlePutsAndGets(cmdShare_t* pCmdShare,const char* command){
    //切分命令和参数
    char tempCommand[4096] = {0};
    memcpy(tempCommand,command,strlen(command));
    /* printf("tempCommand = %s\n",tempCommand); */
    char* order;
    char* arguments[1024];
    int arglen;
    arglen = 0;
    char* saveptr;
    char argv[4096] = {0};
    order = strtok_r(tempCommand," ",&saveptr);
    if(order!=NULL){
        ++arglen;
    }
    memcpy(argv,saveptr,strlen(saveptr));
    /* printf("order = %s,argv = %s\n",order,argv); */
    for(int i=0;i<1024;++i){
        arguments[i] = strtok_r(NULL," ",&saveptr);
        if(arguments[i]==NULL){
            break;
        }
        ++arglen;    
    }

    if(memcmp("puts",order,strlen(order))==0){
        /* printf("puts will execute!\n"); */
        serverExecPuts(pCmdShare,arguments[arglen-2]);
        return 0;
    }
    if(memcmp("gets",order,strlen(order))==0){
        /* printf("gets will execute!\n"); */
        serverExecGets(pCmdShare,argv);
        return 0;
    }
    return -1;
}

int commandDetach(int netfd,int epfd,MYSQL* mysql,redisContext* redis,cmdShare_t* netfdToPcmd[],threadPool_t* pthreadPool,timeoutShare_t* pTimeoutShare){
    //处理超时集合
    //1.将netfd从老位置移除
    delNetfd(pTimeoutShare,netfd);
    //2.将netfd将入集合中新的位置
    joinSet(pTimeoutShare,netfd);
    //对token请求进行分析
    //获取请求
    char request[4096]={0};
    int rret = recvRequest(netfd,request);
    if(rret == -1){ //客户端断开连接
        epollDEL(epfd,netfd);
        delNetfd(pTimeoutShare,netfd);
        free(netfdToPcmd[netfd]);
        close(netfd);
    }
    /* printf("request = %s\n",request); */
    //分隔字段
    char id[1024] ={0};
    char token[1024]={0};
    char command[4096] = {0};
    fieldSeparation(request,id,token,command);
    /* printf("reqFirst = %s,reqSecond = %s,reqThird = %s\n",id,token,command); */
    if(memcmp(token,"1",strlen("1")+1)==0){
        //token为"1"表示注册
        //进行注册
        char username[1024] ={0};
        /* printf("main username = %s\n",username); */
        int ret = userRegister(netfd,mysql,redis,id,username); //id实际上为5位随机数,token验证的id为随机数+用户名
        if(ret == 0){
            //注册成功
            /* printf("Registration successful!\n"); */
            SYSTEM_LOG(LOG_NOTICE,username,"Registration successful");
            //创建给用户的命令的共享变量，并将netfd和pCmdshare的映射关系存入netfdToPcmd数组中
            cmdShare_t* pCmdShare = (cmdShare_t*)malloc(sizeof(cmdShare_t));
            cmdShareInit(pCmdShare,netfd,mysql,username);
            netfdToPcmd[netfd] = pCmdShare;
            return 0;
        }else{
            //注册失败 
            printf("Registration failed!\n");
            SYSTEM_LOG(LOG_NOTICE,username,"Registration failed");
            return -1;
        }
    }else if(memcmp(token,"2",strlen("2")+1)==0){ 
        //token为"2"表示登录
        //进行登录
        char username[1024] = {0};
        int ret = serverPwdAuth(netfd,mysql,redis,id,username);
        if(ret == 0){
            //登录成功
            /* printf("Connection successful!\n"); */
            SYSTEM_LOG(LOG_NOTICE,username,"Connection successful");
            //创建给用户的命令的共享变量，并将netfd和pCmdshare的映射关系存入netfdToPcmd数组中
            cmdShare_t* pCmdShare = (cmdShare_t*)malloc(sizeof(cmdShare_t));
            cmdShareInit(pCmdShare,netfd,mysql,username);
            netfdToPcmd[netfd] = pCmdShare;
            return 0;
        }else{
            //登录失败 
            printf("Connection failed!\n");
            SYSTEM_LOG(LOG_NOTICE,username,"Connection failed");
            return -1;
        }
    }
    //不是登录和注册命令
    //进行token验证
    int ret = tokenVerify(id,token);
    if(strlen(id)==0||strlen(token)==0){
        //参数个数不对
        ret = -1;
    }
    /* printf("ret = %d\n",ret); */
    train_t train;
    if(ret != 0){
        //token验证不通过,通知客户端
        memset(&train,0,sizeof(train_t));
        train.length = strlen("-1");
        memcpy(train.data,"-1",train.length);
        send(netfd,&train.length,sizeof(train.length),0);
        send(netfd,train.data,train.length,0);
        return 0;
    }
    if(ret == 0){
        //token验证通过
        memset(&train,0,sizeof(train_t));
        train.length = strlen("0");
        memcpy(train.data,"0",train.length);
        send(netfd,&train.length,sizeof(train.length),0);
        send(netfd,train.data,train.length,0);
    }
    //不是登录和注册命令
    //通过id获取username
    char username[1024] ={0};
    getusername(id,username); 
    //查找命令的共享变量
    cmdShare_t* pCmdShare = netfdToPcmd[netfd];
    /* printf("username = %s,command =%s\n",username,command); */
    //解析命令
    //切分命令和参数
    char tempCommand[4096] = {0};
    memcpy(tempCommand,command,strlen(command));
    /* printf("tempCommand = %s\n",tempCommand); */
    char* order;
    int arglen;
    arglen = 0;
    char* saveptr;
    order = strtok_r(tempCommand," ",&saveptr);

    if(memcmp(order,"gets",sizeof("gets"))==0||memcmp(order,"puts",sizeof("puts"))==0){
        //是长命令
        //是上传下载操作,不用监听,由子线程和客户端子线程直接通信
        epollDEL(epfd,netfd);
        delNetfd(pTimeoutShare,netfd);

        //验证成功,构建任务
        char username[1024] = {0};
        getusername(id,username);
        task_t task;
        task.netfd = netfd;
        memset(task.username,0,sizeof(task.username));
        memcpy(task.username,username,strlen(username)+1);
        memset(task.command,0,sizeof(task.command));
        memcpy(task.command,command,strlen(command)+1);
        //将任务加入队列
        pthread_mutex_lock(&pthreadPool->mutex);      //加锁
        enQueue(&pthreadPool->taskQueue,task);        // 入队
        printf("I am master,I send a netfd = %d\n",netfd); 
        pthread_cond_signal(&pthreadPool->cond);      //通知
        pthread_mutex_unlock(&pthreadPool->mutex);    //解锁
    }
    //执行命令短命令
    int cret = serverExecCommand(pCmdShare,command); 
    return cret;
} 
